package com.jumi.microservice.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.HttpMethod;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.GeneratePresignedUrlRequest;
import com.aliyun.oss.model.PolicyConditions;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest;
import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
import com.jumi.microservice.service.OssAuthService;
import org.springframework.stereotype.Service;

import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static com.aliyun.oss.internal.OSSConstants.DEFAULT_OBJECT_CONTENT_TYPE;

/**
 * @author liu
 * @since 2020-07-18
 */
@Service
public class OssAuthServiceImpl implements OssAuthService {
    static String ROLE_SESSION_NAME = "web-cdn-oss";
    static String OSS_ARN = "acs:ram::1367445965490699:role/web-cdn-oss";
    static String OSS_STS_ACCESS_ID = "LTAI4G5q7JFrEQHVmwQS9u3h";
    static String OSS_ACCESE_SECRET = "bvJObQjoqwt3s82z3bfqc30htBGj3B";

    /**
     * oss图片鉴权
     *
     * @return
     */
    @Override
    public Object ossAuth() {
        // Endpoint以杭州为例，其它Region请按实际情况填写。
        String endpoint = "oss-cn-beijing.aliyuncs.com";
        String bucketName = "jumituan";
        String objectName = "data/upload/mobile/share/poster/";
        String visitUrl = "https://img.jumituangou.com";
        String region = "oss-cn-beijing";
        Map<String, String> securityToken = token();
        if (securityToken == null) {
            return null;
        }

        // 获取STS临时凭证后，您可以通过其中的安全令牌（SecurityToken）和临时访问密钥（AccessKeyId和AccessKeySecret）生成OSSClient。
        OSS ossClient = new OSSClientBuilder().build(endpoint, securityToken.get("accessKeyId"), securityToken.get("accessKeySecret"), securityToken.get("securityToken"));
        // 设置URL过期时间为1小时。
        Date expiration = new Date(System.currentTimeMillis() + 3600 * 1000);

        /*policy start*/
        PolicyConditions policyConds = new PolicyConditions();
        policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
        String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
        byte[] binaryData = postPolicy.getBytes(StandardCharsets.UTF_8);
        String encodedPolicy = BinaryUtil.toBase64String(binaryData);
        /*policy end*/

        GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, objectName, HttpMethod.PUT);
        request.setExpiration(expiration);
        // 设置ContentType。
        request.setContentType(DEFAULT_OBJECT_CONTENT_TYPE);
        // 生成签名URL。
        URL signedUrl = ossClient.generatePresignedUrl(request);
        String stringSignedUrl = signedUrl.toString();
        stringSignedUrl = stringSignedUrl + "&ossAccessKeySecret=" + securityToken.get("accessKeySecret") + "&bucketName=" + bucketName + "&endpoint=" + endpoint+"&policy="+encodedPolicy+"&visitUrl="+visitUrl+"&region="+region;

      /*  Map<String, String> requestHeaders = new HashMap<String, String>();
        requestHeaders.put(HttpHeaders.CONTENT_TYPE, DEFAULT_OBJECT_CONTENT_TYPE);
        requestHeaders.put(OSS_USER_METADATA_PREFIX + "author", "aliy");
        // 使用签名URL上传文件。
        ossClient.putObject(signedUrl, new ByteArrayInputStream("Hello OSS".getBytes()), -1, requestHeaders, true);*/

        // 关闭OSSClient。
        ossClient.shutdown();
        int lengthOf = stringSignedUrl.indexOf("?")+1;
        String substring = stringSignedUrl.substring(lengthOf);
        String[] arr = substring.split("&"); // 用,分割
        Map<String, String> stringArr = new HashMap<>();
        for (String arrs : arr) {
            String[] split = arrs.split("=");
            stringArr.put(split[0],split[1]);
        }
        JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(stringArr));
        return jsonObject;
    }

    private static Map<String, String> token() {
        String policy = "{" +
                "    \"Version\": \"1\", " +
                "    \"Statement\": [" +
                "        {" +
                "            \"Action\": [" +
                "                \"oss:*\"" +
                "            ], " +
                "            \"Resource\": [" +
                "                \"acs:oss:*:*:*\" " +
                "            ], " +
                "            \"Effect\": \"Allow\"" +
                "        }" +
                "    ]" +
                "}";

        //构建一个阿里云客户端，用于发起请求。方法位于stssdk文档
        //构建阿里云客户端时需要设置AccessKey ID和AccessKey Secret。
        DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", OSS_STS_ACCESS_ID, OSS_ACCESE_SECRET);
        IAcsClient client = new DefaultAcsClient(profile);

        //构造请求，设置参数。
        AssumeRoleRequest request = new AssumeRoleRequest();
        request.setRegionId("cn-beijing");
        request.setRoleArn(OSS_ARN);
        request.setRoleSessionName(ROLE_SESSION_NAME);
        request.setPolicy(policy); // 若policy为空，则用户将获得该角色下所有权限
        //发起请求，并得到响应。
        Map<String, String> map = new HashMap<>();
        try {
            AssumeRoleResponse response = client.getAcsResponse(request);
            map.put("securityToken",response.getCredentials().getSecurityToken());
            map.put("accessKeySecret",response.getCredentials().getAccessKeySecret());
            map.put("accessKeyId",response.getCredentials().getAccessKeyId());
            map.put("requestId",response.getRequestId());
            //jsonStr = new Gson().toJson(response);
            //jsonStr = response.getCredentials().getSecurityToken();
            //response.getCredentials().getSecurityToken();
            //System.out.println(new Gson().toJson(response));
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            System.out.println("ErrCode:" + e.getErrCode());
            System.out.println("ErrMsg:" + e.getErrMsg());
            System.out.println("RequestId:" + e.getRequestId());
        }
        return map;
    }

  /* public static void main(String[] args) {
        OssAuthServiceImpl ossAuthService = new OssAuthServiceImpl();
        ossAuthService.ossAuth();
    }*/
}
